package com.hyphenate.easeui.map;

import android.app.IntentService;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;

import com.e.library.utils.EGsonUtils;
import com.hyphenate.easeui.R;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by e on 2017/8/16.
 */

public class AddressService extends IntentService {

    public static final String EXTRA_RECEIVER = "Receiver";
    public static final String EXTRA_LATITUDE = "Latitude";
    public static final String EXTRA_LONGITUDE = "Longitude";
    public static final String EXTRA_FAILURE = "failure";
    public static final String EXTRA_ADDRESS = "address";
    public static final String EXTRA_REGION = "region";
    public static final int RESULT_FAILURE = 1;
    public static final int RESULT_SUCCESS = 2;

    private static final String TAG = "AddressService";
    protected ResultReceiver mReceiver;

    public AddressService() {
        super("AddressService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {

        String errorMessage = "";

        mReceiver = intent.getParcelableExtra(EXTRA_RECEIVER);
        if (mReceiver == null) {
            return;
        }

        double lat = intent.getDoubleExtra(EXTRA_LATITUDE,0);
        double lng = intent.getDoubleExtra(EXTRA_LONGITUDE,0);
        Log.i(TAG,String.valueOf(lng));
        Log.i(TAG,String.valueOf(lat));

        Geocoder geocoder = new Geocoder(this, Locale.getDefault());
        try {
            List<Address> addresses = geocoder.getFromLocation(lat, lng, 1);
            onGeoCoder(addresses);
        } catch (IOException ioException) {
            // Catch network or other I/O problems.
            fetchAddress(lat,lng);
            Log.e(TAG, errorMessage, ioException);
        } catch (IllegalArgumentException illegalArgumentException) {
            // Catch invalid latitude or longitude values.
            failure(getResources().getString(R.string.ease_map_geo_invalid));
        }

    }

    private void onGeoCoder(List<Address> addresses){
        if(addresses == null || addresses.isEmpty()) {
            failure(getResources().getString(R.string.ease_map_geo_invalid));
        }else {
            Address address = addresses.get(0);

            StringBuilder sb = new StringBuilder();
            /**省+市+区+道路*/
            sb.append(address.getAdminArea());
            sb.append(address.getLocality());
            sb.append(address.getSubLocality());
            sb.append(address.getThoroughfare());

            for(int i = 0; i < address.getMaxAddressLineIndex(); i++) {
                sb.append(address.getAddressLine(i));
            }

            Log.i(TAG,sb.toString());
            successful(address.getThoroughfare(),sb.toString());
        }
    }

    private void successful(String region,String address){
        Bundle bundle = new Bundle();
        bundle.putString(EXTRA_REGION, region);
        bundle.putString(EXTRA_ADDRESS, address);
        mReceiver.send(RESULT_SUCCESS, bundle);
    }

    private void failure(String message) {
        Bundle bundle = new Bundle();
        bundle.putString(EXTRA_FAILURE, message);
        mReceiver.send(RESULT_FAILURE, bundle);
    }

    private void fetchAddress(double lat,double lng){
        OkHttpClient client = new OkHttpClient.Builder()
                .readTimeout(15, TimeUnit.SECONDS)
                .connectTimeout(15,TimeUnit.SECONDS)
                .build();

        StringBuilder url = new StringBuilder();
        url.append("http://maps.googleapis.com/maps/api/geocode/json?latlng=").append(lat).append(",").append(lng);
        url.append("&sensor=false&language=").append(Locale.getDefault().getCountry());
        Log.i(TAG,url.toString());
        Request request = new Request.Builder().url(url.toString()).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                failure(getResources().getString(R.string.ease_google_service_invalid));
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                Log.i(TAG,json);
                onFetchAddress(json);
            }
        });
    }


    private void onFetchAddress(String json){
        try {
            JSONObject object = new JSONObject(json);
            if(!object.has("results") || object.isNull("results")) {
                return;
            }

            JSONArray results = object.getJSONArray("results");
            if(results.length() <=0) {
                return;
            }

            JSONObject item = results.getJSONObject(0);
            if(item.has("formatted_address") && !item.isNull("formatted_address")) {
                String address = item.getString("formatted_address");
                String region = "";

                JSONArray components = item.getJSONArray("address_components");
                int length = components.length();
                for (int i=0;i<length;i++){
                    JSONObject com = components.getJSONObject(i);
                    List<String> types = EGsonUtils.toList(com.getString("types"),String.class);
                    if(types !=null && types.contains("route")) {
                        region = com.getString("short_name");
                        break;
                    }
                }

                successful(region,address);
            }

        }catch (Exception e){
            e.printStackTrace();
            failure(getResources().getString(R.string.ease_google_service_invalid));
        }
    }

}
